package mbsl.ui;

import static mbsl.util.SWTUtils.Direction.down;
import static mbsl.util.SWTUtils.Direction.left;
import static mbsl.util.SWTUtils.Direction.right;
import static mbsl.util.SWTUtils.Direction.up;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Spinner;

import mbsl.util.SWTUtils;

public class SpinnerPanel {
	/**
	 * Creates a panel with a check box and a spinner.
	 * <p>
	 * The check box is used to turn the other spinner on or off. If you
	 * don't want to set a value, you uncheck the check box.
	 * <p>
	 * The default selected value will be the minimum value.
	 * @see #SpinnerPanel(Composite, int, int, int)
	 * @param pParent The parent Composite.
	 * @param pMaxValue The maximum allowed value.
	 * @param pMinValue The minimum allowed value.
	 */
	public SpinnerPanel(Composite pParent, int pMaxValue, int pMinValue) {
		this(pParent, pMaxValue, pMinValue, MINIMUM);
	}
	/**
	 * Creates a panel with a check box and a spinner.
	 * <p>
	 * The check box is used to turn the other spinner on or off. If you
	 * don't want to set a value, you uncheck the check box.
	 * @see #SpinnerPanel(Composite, int, int) 
	 * @param pParent The parent Composite.
	 * @param pMaxValue The maximum allowed value.
	 * @param pMinValue The minimum allowed value.
	 * @param pDefaultValue The default value, selected if no other is specified.  Pass MAXIMUM to set the maximum allowed value as default, and MINIMUM to set the minimum allowed value as default.
	 */
	public SpinnerPanel(Composite pParent, int pMaxValue, int pMinValue, int pDefaultValue) {
		mPanel = new Composite(pParent, SWT.NONE);
		
		if (pMinValue < 0)
			pMinValue = 0;
		if (pMaxValue < pMinValue)
			pMaxValue = pMinValue;
		
		mMaxValue = pMaxValue;
		mMinValue = pMinValue;
		
		switch (pDefaultValue) {
			case MAXIMUM:
				mDefaultValue = mMaxValue;
				break;
			case MINIMUM:
				mDefaultValue = mMinValue;
				break;
			default:
				mDefaultValue = pDefaultValue;
				break;
		}
		
		setUpComponents();
	}
	
	public void setValue(Integer pValue) {
		if (pValue == null)
			activateControls(false);
		else {
			mSpinner.setSelection(pValue);
			
			activateControls(true);
		}
	}
	public Integer getValue() {
		if (!mCheckBox.getSelection())
			return null;
		else
			return mSpinner.getSelection();
	}
	/** Returns the Composite holding the components of this panel. */
	public Composite getWidget() {
		return mPanel;
	}
	
	/** Sets up the components */
	private void setUpComponents() {
		mPanel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDoubleClick(MouseEvent pE) {
				activateControls(true);
			}
		});
		mPanel.addMouseWheelListener(new MouseWheelListener() {
			@Override
			public void mouseScrolled(MouseEvent pE) {
				if (mSpinner.isEnabled())
					mSpinner.setSelection(mSpinner.getSelection() + pE.count / 2);
			}
		});
		mPanel.setLayout(new FormLayout());

		createCheckBox();
		createSpinner();
	}
	/** Sets up the check box */
	private void createCheckBox() {
		mCheckBox = new Button(mPanel, SWT.CHECK);
		
		mCheckBox.setLayoutData(SWTUtils.getFormData(
				SWTUtils.getMeta(up, 0, 0),
				SWTUtils.getMeta(down, 100, 0),
				SWTUtils.getMeta(left, 0, 0),
				SWTUtils.getMeta(right, 0, 15)
		));
		
		mCheckBox.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent pE) {
				activateControls(mCheckBox.getSelection());
			}
		});
	}
	/** Sets up the spinner */
	private void createSpinner() {
		mSpinner = new Spinner(mPanel, SWT.READ_ONLY);
		
		mSpinner.setLayoutData(SWTUtils.getFormData(
				SWTUtils.getMeta(up, 0, 0),
				SWTUtils.getMeta(down, 100, 0),
				SWTUtils.getMeta(left, 0, 15),
				SWTUtils.getMeta(right, 100, 0)
		));
		mSpinner.setMaximum(mMaxValue);
		
		mSpinner.setMinimum(mMinValue);

		mSpinner.setSelection(mDefaultValue);
	}
	/** Activates/deactivates the controls */
	private void activateControls(boolean pDoActivate) {
		mCheckBox.setSelection(pDoActivate);
		mSpinner.setEnabled(pDoActivate);
	}
	
	/** Signals that the maximum allowed value will be set as the default. */
	public static final int MAXIMUM = Integer.MAX_VALUE;
	/** Signals that the minimum allowed value will be set as the default. */
	public static final int MINIMUM = Integer.MIN_VALUE;
	
	private Composite mPanel;
	private Button mCheckBox;
	private Spinner mSpinner;
	private int mMaxValue;
	private int mMinValue;
	private int mDefaultValue;
}
